#!/usr/bin/env python
# -*- encoding: utf-8 -*-
import sys


class XDictUtils(object):
    """XDictUtils is a set of utilities and accessory methods usable with Python dicts.

    Usage::
    # 1. Search for a value in a dictionary, passing a key:
    from from xpy3lib.utils.XDictUtils import XDictUtils
    dict_1 = {'first_level': {'second_level': {'name': 'Joe', 'age': 30}}}
    # found_value will contain 'Joe'
    found_value = XDictUtils.search_value(p_dict=dict_1, p_key='name')

    # 2.Compare two different dictionaries having the same keys
    from from xpy3lib.utils.XDictUtils import XDictUtils
    dict_1 = {'first_level': {'second_level': {'name': 'Joe', 'age': 30}}}
    dict_2 = {'level_1': {'level_2': {'name': 'Joe', 'age': 30}}}
    equals = XDictUtils.compare(p_fields=['name', 'age'], p_dict_1=dict_1, p_dict_2=dict_2)
    """

    @staticmethod
    def search_value(p_dict=None, p_key=None):
        """Search for a key inside a dictionary, visiting it in a recursive way and return the value of this key.

        :param p_dict:dictionary to search into
        :param p_key:key name to search for
        :return:
        """
        if type(p_dict) == dict:
            for k, v in p_dict.items():
                if type(v) == dict:
                    value = XDictUtils.search_value(p_dict=v, p_key=p_key)
                    if value:
                        return value
                if type(v) == list:
                    if len(v) > 0:
                        for element in v:
                            if type(element) == dict:
                                value = XDictUtils.search_value(p_dict=element, p_key=p_key)
                                if value:
                                    return value
                if k == p_key:
                    return v
        return None

    @staticmethod
    def compare(p_fields=None, p_dict_1=None, p_dict_2=None):
        """Given a list of fields/keys and two dictionaries, it searches for each key in both
        dictionaries and assert as equal the found value.

        :param p_fields: a list of fields/keys to verify
        :param p_dict_1: 1st dictionary
        :param p_dict_2: 2nd dictionary
        :return:
        """
        b = True
        for field in p_fields:
            value_1 = XDictUtils.search_value(p_dict=p_dict_1, p_key=field)
            value_2 = XDictUtils.search_value(p_dict=p_dict_2, p_key=field)

            if type(value_1) is list:
                value_1 = list(value_1).sort()
            if type(value_2) is list:
                value_2 = list(value_2).sort()

            b = b & (str(value_1) == str(value_2))
        return b
